package cn.sangedon.review.data.service.impl;

import cn.sangedon.review.common.constant.CacheConstant;
import cn.sangedon.review.common.domain.data.StockDayInfo;
import cn.sangedon.review.common.query.data.StockDayInfoQuery;
import cn.sangedon.review.common.service.data.CacheService;
import cn.sangedon.review.common.service.data.StockDayInfoService;
import cn.sangedon.review.common.service.data.TradingDateService;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.util.CollectionUtils;

@EnableScheduling
@Slf4j
@DubboService
public class CacheServiceImpl implements CacheService {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private TradingDateService tradingDateService;

    @Autowired
    private StockDayInfoService stockDayInfoService;

    @Override
    public void refreshStockDayInfo() {
        refreshStockDayInfo(20);
    }

    @Override
    public void refreshStockDayInfo(Integer days) {
        log.info("开始初始化股市近期交易数据缓存");
        List<String> tradingDays = tradingDateService.getLatestTradingDay(days);
        if (CollectionUtils.isEmpty(tradingDays)) {
            log.info("未查询到近{}个交易日", days);
            return;
        }

        String cacheKey = CacheConstant.LATEST_TRADING_INFO + days;
        Set<String> keys = redisTemplate.opsForHash().keys(cacheKey);
        Boolean allSame = keys.size() > 0;
        for (String key : keys) {
            if (!tradingDays.contains(key)) {
                allSame = false;
                redisTemplate.opsForHash().delete(cacheKey, key);
            }
        }
        if (allSame) {
            log.info("缓存数据已存在, 无需更新");
            return;
        }

        StockDayInfoQuery query = new StockDayInfoQuery();
        query.setStartTime(tradingDays.get(tradingDays.size() - 1));
        query.setEndTime(tradingDays.get(0));
        List<StockDayInfo> stockDayInfos = stockDayInfoService.getStockDayInfos(query);
        Map<String, List<StockDayInfo>> listMap = stockDayInfos.parallelStream()
                                                               .collect(Collectors.groupingBy(StockDayInfo::getTradingDate));
        redisTemplate.opsForHash().putAll(cacheKey, listMap);
        log.info("股市近期交易数据缓存初始化: 成功");
    }
}
